#!/usr/bin/env python
# Copyright (C) 
# 
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
# 
##
# @file dirmanager.py
# @Synopsis: A small tool used to orginize files in a directory using their modified time
# @author hkuieagle
# @version 0.0.2
# @date 2011-09-19
# @usage: Use cron or likeness to add this file to be executed every hour 

import time, shutil, os, syslog
import getopt, sys
year_list = []
month_list = []
day_list = []
hour_list = []

separator = '-'
conf_file = "/home/hk/.dirmanager.conf"

directory = ""
occasion = ""

Version = "0.0.2"
daemon = False 

def manager(dir_name, accord):
    if not os.path.exists(dir_name):
        log(syslog.LOG_WARNING, "No directory: %s exists" %dir_name)
        return
    pool_root = dir_name + '/' + 'pool'
    if not os.path.exists(pool_root):
        os.makedirs(pool_root)
    filelist = os.listdir(dir_name)
    for rel_filename in filelist:
        filename = dir_name + '/' + rel_filename
        if os.path.isfile(filename):
            mtime =  time.localtime(os.path.getmtime(filename))
            str_hour = '%.2d:00' %mtime.tm_hour
            str_day = '%.2d' %mtime.tm_mday
            str_month = '%.2d' %mtime.tm_mon
            str_year = '%d' %mtime.tm_year
            if accord == 'hour':
                dir_move_to = dir_name + '/' + separator.join([str_year, str_month, str_day]) + '/' + str_hour
                rel_dir_move_to = '../' + separator.join([str_year, str_month, str_day]) + '/' + str_hour      # $rel_dir_move_to is used to make relative symlinks in pool directory so that you can change the folder name without breaking the symlinks in pool.
            elif accord == 'day':
                dir_move_to = dir_name + '/' + separator.join([str_year, str_month]) + '/' + str_day + 'd'
                rel_dir_move_to = '../' + separator.join([str_year, str_month]) + '/' + str_day + 'd'
            elif accord == 'month':
                dir_move_to = dir_name + '/' + str_year + '/' + str_month + 'm'
                rel_dir_move_to = '../' + str_year + '/' + str_month + 'm'
            elif accord == 'year':
                dir_move_to = dir_name + '/' + str_year
                rel_dir_move_to = '../' + str_year
            else:
                log(syslog.LOG_ERR, "Unknown accord!")
                return
            if not os.path.exists(dir_move_to):
                os.makedirs(dir_move_to)
            dst_file = dir_move_to + '/' + rel_filename
            rel_dst_file = rel_dir_move_to + '/' +rel_filename
            if not os.path.exists(dst_file):
                shutil.move(filename, dir_move_to)
            symfile = pool_root + '/' + rel_filename
            if not os.path.exists(symfile):
                os.symlink(rel_dst_file, symfile)

def usage():
    print '''Usage:
        dirmanager -d dir:          manager dir with 'day' as the default occasion.
        dirmanager -d dir -o oca:   manager dir with oca as the occasion.
        dirmanager -V:              show the version.
        dirmanager -h:              show help.
        dirmanager -f file:         use file as the configure file. 
                                    default is /home/username/.dirmanager.conf'''

def version():
    print ''' Version: %s
 Bug report: hkuieagle@gmail.com''' %Version

def log(priority, string):
    if daemon == True:
        syslog.syslog(priority, string)
    else:
        print "%s: %s" %(priority, string)

if __name__ == '__main__':
    try:
        opts, args = getopt.getopt(sys.argv[1:], "-hVd:o:f:", ["help", "version", "directory=", "occasion=", "file="])
    except getopt.GetoptError, err:
        print str(err)
        usage()
        sys.exit(2)

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
            sys.exit(0)
        elif o in ("-V", "--version"):
            version()
            sys.exit(0)
        elif o in ("-d", "--directory"):
            directory = a
        elif o in ("-o", "--occasion"):
            occasion = a
        elif o in ("-f", "--file"):
            conf_file = a
        else:
            assert False, "unhandled option"

    if occasion != "" and directory == "":
        log("ERROR", "directory is needed with an occasion")
        sys.exit(2)

    if directory != "":                                    # cmdline mode
        if occasion != "":
            manager(directory, occasion)
        else:
            manager(directory, 'day')
    else:                                                   # directory == "", daemon mode
        daemon = True
        log(syslog.LOG_INFO, "dirmanager starts to manager directories:")
        cfile = file(conf_file, 'r')
        for line in cfile:
            if len(line.strip()) == 0 or line.strip()[0] == '#':
                continue
            (dirt, accord) = line.split(':')
            dirt = dirt.strip()
            accord = accord.strip()
            log(syslog.LOG_INFO,line.strip())
            if accord == 'year':
                year_list.append(dirt)
            elif accord == 'month':
                month_list.append(dirt)
            elif accord == 'day':
                day_list.append(dirt)
            elif accord == 'hour':
                hour_list.append(dirt)

        for dirt in hour_list:
            manager(dirt, 'hour')

        for dirt in day_list:
            manager(dirt, 'day')

        for dirt in month_list:
            manager(dirt, 'month')

        for dirt in year_list:
            manager(dirt, 'year')

